package com.project.bookstore.config.security;

import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@Slf4j
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Value("${mine.JWT.secreteKey}")
    private String secreteKey;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authenticationJWT = request.getHeader("Authentication");
        if (!StringUtils.hasText(authenticationJWT)){
//            log.debug("请求头同没有 authenticationJWT 直接放行");
            filterChain.doFilter(request,response);
            //阻止后面的代码回来执行
            return;
        }
//        log.debug("准备解析 jwt...");
        Claims claims = null;
        String username = " ";
        List<SimpleGrantedAuthority> permissions = null;
        try {
            claims = Jwts.parser().setSigningKey(secreteKey).
                    parseClaimsJws(authenticationJWT).getBody();
            username = (String) claims.get("username");
            String password = (String) claims.get("password");
            String  permissionsJson = (String) claims.get("permissions");
            permissions =
                    JSON.parseArray(permissionsJson, SimpleGrantedAuthority.class);
//            log.debug("解析到的：username:【{}】;password:【{}】;permissions:【{}】"
//                    ,username,password,permissions);
            //认证需要 Authentication 下面是他的实现类，其中 permission GrantedAuthority 的实现类 SimpleGrantedAuthority
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(username, null, permissions);
            //放到 security 上下文中
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
//            log.debug("成功将数据放到 security 上下文中，框架会自动处理");
        } catch (ExpiredJwtException | IllegalArgumentException | SignatureException | MalformedJwtException | UnsupportedJwtException e) {
            log.warn("security 认证时 jwt 过期或者解析失败...");
        }finally {
            //放行
            filterChain.doFilter(request,response);
        }
    }
}
